#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"
using namespace TcpServerModule;

using http_handler_t = std::function<void (HttpRequest &,HttpResponse&)>;

class HttpServer
{
public:
    HttpServer(int port)
        : _tsvr(std::make_unique<TcpServer>(port))
    {
    }

    void Resgiterstd(std::string fucname,http_handler_t handler)
    {
        _handlers[fucname] = handler;//功能函数用hash表封装起来,这里是添加函数
        
    }
    bool SafeCheck(const std::string& service)
    {
        auto iter=_handlers.find(service);
        return iter!=_handlers.end();
    }
    void Start()
    {
        std::cout << "start http server" << std::endl;
        _tsvr->InitServer([this](SockPtr sockfd, InetAddr client)
                          { return this->HandlereHttpRequest(sockfd, client); });
        _tsvr->Loop();
    }

    // 只需要关心这部分代码就可以改变基于http协议的网络通信功能！！
    bool HandlereHttpRequest(SockPtr sockfd, InetAddr client)
    {
        std::cout << "get a new client" << sockfd->Fd() << "addr info:" << std::endl;
        std::string http_request;
        sockfd->Recv(&http_request);
        // vesion--2  增加协议
        HttpRequest req;
        req.Deserialize(http_request);
        HttpResponse resp;

        // req.Print();
        // 解析请求，获取请求的资源路径，并根据资源路径返回响应数据
        // URI——请求资源路径

        // 请求有两种：
        //  1.请求一般的静态资源。
        //  2.提交参数，携带参数，需要我们交互设置。
        if (req.IsHasArgs())
        {
            // 处理情况二：POST方法根据你携带的参数去做出不同的应答。
            //如果带参数，直接回调hash中注册的功能。
            //安全处理，路由功能必须是我服务器中有的功能
           std::cout << "-----IsHasArgs()" << std::endl;
            std::string service=req.Path();
            
            if(SafeCheck(service)) 
                _handlers[req.Path()](req,resp);
            else
            {
                resp.Build(req);//debug,Build一定失败，所以一定是404
            }
        }
        else
        {
            // 处理情况一：GET方法：是直接获取HTTP协议的响应协议
            //Build是直接获取HTTP协议的响应协议
           std::cout << "-----Non IsHasArgs()" << std::endl;
            resp.Build(req);
        }
        std::string resp_str;
        // 序列化
        resp.Serialize(&resp_str);
        // 返回信息
        sockfd->Send(resp_str);

        // 读取请求，对请求进行分析处理--->本质上是文本处理！！
        // 1.读取请求的完整性--HTTP这里暂时不做，因为和我们学的内容是HTTP关联度不大。
        // 2. 序列化和反序列化
        // vesion-1——demo1:先直观的观察一下，没有具体协议的纯字符串处理。
        // 对大小写不敏感都可以版本一般是http/版本号
        // std::string status_line = "HTTP/1.1 200 OK" + sep + BlankLine;
        // 直接返回一个html网页,这是硬编码，实际上应该从文件中读取
        /*std::string body = "<!DOCTYPE html>\
                            <html>\
                            <head>\
                            <meta charset=\"UTF-8\">\
                            <title>Hello World</title>\
                            </head>\
                            <body>\
                            <hello world\
                            </body>\
                            </html>";

        // std::string httpresponse = status_line + body;
        // sockfd->Send(httpresponse);
        */
        return true;
    }

    ~HttpServer() {}

private:
    std::unique_ptr<TcpServer> _tsvr;
    std::unordered_map<std::string, http_handler_t> _handlers;//功能路由
};
